<script setup lang="ts">
import type { PropType } from "vue";
import designComponents from "../../components/designComponents";
import { newRandomUid } from "@/utils";

const props = defineProps({
  modelValue: {
    type: Array as PropType<Array<any>>,
    required: true,
  },
  select: {
    type: String,
    default: "",
  },
  parent: {
    type: Object as PropType<any>,
    default: () => ({}),
  },
});

const activityReadonly = inject("activityReadonly", false),
  pageList: any = inject("pageList"),
  changeTab: any = inject("changeTab"),
  autoSorting: any = inject("autoSorting");
const emits = defineEmits(["update:modelValue", "change"]);

const componentRef = ref({}),
  componentsRef = ref();

// 切换关联数据
const changeink = ($el: any) => {
  if (!$el.link || $el.link.length === 0) {
    $el.pageConfig.$pageFlag = `${$el.type}-${newRandomUid()}`;
  } else {
    let link = $el.link.split("_");
    let linkPage = pageList.value.find((page: any) => page.uid === link[0]);
    let linkEl = linkPage.configList.find((el: any) => el.uid === link[1]);
    $el.pageConfig.$pageFlag = linkEl.pageConfig.$pageFlag;
  }
  onChange();
};

const update = (value = {}, newConfig: any = null, type = "after") => {
  nextTick(() => {
    if (newConfig) {
      let exitEl = props.modelValue.find((item) => item.uid == newConfig.uid);
      if (!exitEl) {
        if (type === "after") {
          props.modelValue.push(newConfig);
        } else if (type === "before") {
          let currentIndex = props.modelValue.findIndex(
            (item) => item.uid === props.select
          );
          props.modelValue.splice(currentIndex, 0, newConfig);
          changeTab(props.select, newConfig.uid);
        }
      }
    }
    onChange();
    autoSorting();
  });
};

// 添加子组件
const appendComponent = (child: any, uid: string) => {
  let $parent = props.modelValue.find((item) => item.uid == uid);
  if ($parent.children) $parent.children.push(child);
  else $parent.children = [child];
  emits("change");
};

const remove = (uid: string) => {debugger
  if (componentRef.value[uid] && componentRef.value[uid].remove) {
    return componentRef.value[uid].remove(props.modelValue);
  } else if (componentsRef.value) return componentsRef.value[0].remove(uid);
};

const check = () => {
  return new Promise(async (resolve, reject) => {
    for (let i = 0; i < props.modelValue.length; i++) {
      if (
          componentRef.value[props.modelValue[i].uid] &&
          componentRef.value[props.modelValue[i].uid].check
      ) {
        try {
          await (componentRef.value[props.modelValue[i].uid] as any).check();
        } catch (e) {
          reject({ message: e, uid: props.modelValue[i].uid });
        }
      }
    }
    if (componentsRef.value) {
      try {
        await componentsRef.value.check();
      } catch (e) {
        reject(e);
      }
    }
    resolve(props.modelValue);
  });
};

const onChange = () => {
  emits("update:modelValue", props.modelValue);
  emits("change");
};

defineExpose({ remove, check });
</script>
<template>
  <template v-for="(item, index) in modelValue" :key="item.uid">
    <div v-show="select === item.uid">
      <div class="form-item">
        <div class="name">组件名称</div>
        <div class="setting">
          <el-input
            v-model="item.name"
            placeholder="请填写组件名称"
            :disabled="activityReadonly"
          ></el-input>
        </div>
      </div>
      <div class="form-item" v-if="item.pageConfig.$pageFlag">
        <div class="name">关联数据</div>
        <div class="setting">
          <el-select
            v-model="modelValue[index].link"
            placeholder="请选择"
            style="width: 200px"
            clearable
            @change="changeink(modelValue[index])"
          >
            <template v-for="page in pageList" :key="page.uid">
              <template
                v-for="component in page.configList"
                :key="`${page.uid}_${component.uid}`"
                ><el-option
                  v-if="
                    component.type === item.type &&
                    component.uid !== item.uid &&
                    !component.link
                  "
                  :label="`【${page.pageName}】${component.name}`"
                  :value="`${page.uid}_${component.uid}`"
              /></template>
            </template>
          </el-select>
        </div>
      </div>
      <component
        :is="designComponents[item.type]"
        :ref="
          (el) => {
            if (el) componentRef[item.uid] = el;
          }
        "
        v-model:config="item.pageConfig"
        :name="item.name"
        :uid="item.uid"
        :info="item"
        :groupType="parent.type"
        :group="parent.children"
        :disabled="activityReadonly"
        @change="update"
        @append="appendComponent($event, item.uid)"
      />
    </div>
    <ActComponentRender
      v-if="item.group"
      ref="componentsRef"
      v-model="item.children"
      :select="select"
      :parent="item"
      @change="update"
    />
  </template>
</template>
<script lang="ts">
export default {
  name: "ActComponentRender",
};
</script>
<style lang="scss" scoped>
.form-item {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  .name {
    font-size: 14px;
  }
  .setting {
    margin-left: 20px;
  }
}
</style>
